package com.dmx.fw.web.struts2.interceptor;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.TokenInterceptor;
import org.apache.struts2.util.TokenHelper;

import com.dmx.fw.constant.ViewConstant;
import com.dmx.fw.exception.GeneralException;
import com.dmx.fw.exception.GeneralExceptionHandler;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.util.LocalizedTextUtil;

public class MixTokenInterceptor extends TokenInterceptor implements com.opensymphony.xwork2.interceptor.PreResultListener{

	public static final String GLOBAL_ERROR_INFO_KEY = ViewConstant.GLOBAL_ERROR_INFO_KEY;
	
	//private static final String GLOBAL_SUCCESS_INFO_KEY = ViewConstant.GLOBAL_SUCCESS_INFO_KEY;
	
	public static final String RE_LOCATION_URL_KEY = ViewConstant.RE_LOCATION_URL_KEY;
	
	
	
	public static final String ERROR_RESULT = "error";
	
	public static final String REPEAT_SUBMIT = "repeat_submit";

	public static final String NO_SAVE_TOKEN = "no_save_token";
	
	public static final String EXCEPTION = "iframe_exception";
	
	//保存action执行结果
	public static final String ACTION_EXEC_RESULT = ViewConstant.ACTION_EXEC_RESULT;

    private static final String NOTOKEN = "noToken";
	
	//session中用于保存上一个action的上下文的key
	//private static final String LAST_ACTION_KEY = "com.dmx.cbill.interceptor.CbillTokenInterceptor";
    
        
    private String oldToken = null;
	
	/**
	 * 重写TokenHelper中的函数
	 * @return
	 */
    protected boolean validToken() {
        oldToken = null;
        Map params = ActionContext.getContext().getParameters();

        String[] noTokens = (String[]) params.get(NOTOKEN);
    	
        //不需要token
        if (noTokens!=null && noTokens.length>0) {
            //页面上没有token，返回
            params.remove(NOTOKEN);
            return true;
        }
        String tokenName = TokenHelper.getTokenName();
        
        if (tokenName == null) {
            return true;
        }
        
        String token = TokenHelper.getToken(tokenName);

        if (token == null) {
            return false;
        }

        Map session = ActionContext.getContext().getSession();
        String sessionToken = null;
        
        if (session!=null)
        	sessionToken = (String) session.get(tokenName);
        
        if (!token.equals(sessionToken)) {
            return false;
        }else{
            oldToken = sessionToken; 
            session.remove(tokenName);
        }
        return true;
    }
    
   public void beforeResult(ActionInvocation invocation, String resultCode) {
        Map session = ActionContext.getContext().getSession();
        HttpServletRequest req = ServletActionContext.getRequest();
        /*if (VALIDATE_ERROR_RESULT.equals(resultCode)){  
        	  //设置error的返回的返回码，转到error.action页面，进行错误信息的显示        
            invocation.setResultCode(ERROR_RESULT); 
            if (session!=null){  
            	session.put(ACTION_EXEC_RESULT, resultCode);
            }else{
            	req.setAttribute(ACTION_EXEC_RESULT, resultCode); 
            }
        }else if (SUCCESS_RESULT.equals(resultCode)){
        	  //设置error的返回的返回码，转到error.action页面，进行成功页面的跳转   
            invocation.setResultCode(ERROR_RESULT);
            if (session!=null){  
            		session.put(ACTION_EXEC_RESULT, resultCode);
            }else{
    		        req.setAttribute(ACTION_EXEC_RESULT, resultCode); 
            }
        }else*/ 
        if (NO_SAVE_TOKEN.equals(resultCode)){
        	  //采用费iframe的方式进行处理，不进行旧的token的保存
            //invocation.setResultCode(ERROR_RESULT);
            if (session!=null){  
            		session.put(ACTION_EXEC_RESULT, resultCode);
            }else{
    		        req.setAttribute(ACTION_EXEC_RESULT, resultCode); 
            }
        }
        
    }
    
    /**
     * @see com.opensymphony.xwork2.interceptor.MethodFilterInterceptor#doIntercept(com.opensymphony.xwork2.ActionInvocation)
     */
    protected String doIntercept(ActionInvocation invocation) throws Exception {
    	String returnVal = null;    	
    	String tokenName = TokenHelper.getTokenName();
    	HttpServletRequest req = ServletActionContext.getRequest();
        Map session = ActionContext.getContext().getSession();
        invocation.addPreResultListener(this);
        synchronized (session) {
        	//清除session中缓存的相关信息
        	clearSessionInfo(session);
        	  //检验是否token有效
            if (!validToken()) {
            	returnVal = ERROR_RESULT;  
            	session.put(ACTION_EXEC_RESULT, REPEAT_SUBMIT);
            	setErrorInfo(session,getMessage("err.system.repeatsubmit"));
            }else{
	            try{
	            	Object o = invocation.getAction();
	            	returnVal =  invocation.invoke();
	            }catch(Exception e){
	            	e.printStackTrace();
	            	GeneralException ge = GeneralExceptionHandler.Handle(e);
	            	if (session!=null){
	            		session.put(ViewConstant.GLOBAL_DETAIL_ERROR_INFO_KEY,e.getMessage());
	            	    session.put(ACTION_EXEC_RESULT, EXCEPTION);
	            	}else{            	      
    		            req.setAttribute(ACTION_EXEC_RESULT, EXCEPTION); 	            		  
	              }
	              returnVal = ERROR_RESULT; //handleInvalidExec(invocation);

	            	setErrorInfo(session,getMessage(ge.getErrorCode()));
	            }
            }
            /*//iframe_error,iframe_exception
            if (VALIDATE_ERROR_RESULT.equals((String)session.get(ACTION_EXEC_RESULT)) || EXCEPTION.equals((String)session.get(ACTION_EXEC_RESULT)) ){
                if (oldToken!=null){
              	  if (session!=null)
                      session.put(tokenName, oldToken);
                }           	
            }*/
                        
        }
        
        return returnVal;
    }
    
    protected void setErrorInfo(Map session,String errorMsg){
    	List errorMsgList = (List)session.get(ViewConstant.GLOBAL_ERROR_INFO_KEY);
    	if (errorMsgList == null){
    		errorMsgList = new ArrayList();    		
    	}
    	errorMsgList.add(errorMsg);
    	if (session!=null){
    		 session.put(ViewConstant.GLOBAL_ERROR_INFO_KEY, errorMsgList);
    	}else{
    		 HttpServletRequest req = ServletActionContext.getRequest();
    		 req.setAttribute(ViewConstant.GLOBAL_ERROR_INFO_KEY, errorMsgList);
      }
    	
    }
    
    /**
     * 清除错误信息
     * @param session
     */
    protected void clearSessionInfo(Map session){
    	if (session!=null){
    		//当是iframe_success标志和不进行信息的清除
    		//if (!SUCCESS_RESULT.equals((String)session.get(ACTION_EXEC_RESULT))){
    		//session.remove(GLOBAL_SUCCESS_INFO_KEY);    	    	
    		//}    		
   			//session.remove(GLOBAL_ERROR_INFO_KEY);
    		
    		//session.remove(ViewConstant.GLOBAL_DETAIL_ERROR_INFO_KEY);
    		
    		session.remove(ViewConstant.ACTION_EXEC_RESULT);
    		session.remove(ViewConstant.RE_LOCATION_URL_KEY);
    		
	    }
    }
    
    protected String getMessage(String key){
        String msg = "";
        try{
           msg = LocalizedTextUtil.findText(this.getClass(), key, ActionContext.getContext().getLocale());
        }catch(Exception e){
            msg = "";
        }
        return msg;
        
    }
    
   
    
    /*protected String callOldInvocation(ActionInvocation invocation) {
        ActionContext ac = invocation.getInvocationContext();

        HttpServletRequest request = (HttpServletRequest) ac.get(ServletActionContext.HTTP_REQUEST);
        Map session = ActionContext.getContext().getSession();
        
        ActionInvocation savedInvocation = null;
        if (session!=null){
        	savedInvocation = (ActionInvocation)session.get(LAST_ACTION_KEY);
        }

        if (savedInvocation != null) {
        	try{
	            // set the valuestack to the request scope
	            //OgnlValueStack stack = savedInvocation.getStack();
	            //ActionContext.getContext().setValueStack(stack);
	            //request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, stack);
	
	            Result result = savedInvocation.getResult();
	
	            if ((result != null) && (savedInvocation.getProxy().getExecuteResult())) {
	                result.execute(invocation);
	            }
	
	            // turn off execution of this invocations result
	            invocation.getProxy().setExecuteResult(false);
	
	            return savedInvocation.getResultCode();
        	}catch(Exception e){
        		return ERROR_RESULT;
        	}
        }

        return ERROR_RESULT;
    }
    */

    /*protected void saveInvocation(ActionInvocation invocation) throws Exception {
        //return invocation.invoke();
        Map session = ActionContext.getContext().getSession();

        if (session == null) {
            throw new IllegalStateException("Unable to access the session.");
        }  
        //ActionInvocation lastSavedInvocation = (ActionInvocation)session.get(LAST_ACTION_KEY);
        
        session.put(LAST_ACTION_KEY, invocation);
        
        String returnVal = null;
        try{
        	returnVal = invocation.invoke();
        }catch(Exception e){
        	//恢复上次保存的ActionInvocation
        	if (lastSavedInvocation!=null){
        		session.put(LAST_ACTION_KEY, lastSavedInvocation);
        	}else{
        		session.remove(LAST_ACTION_KEY);
        	}
        	throw e;
        }
        return returnVal;
    }*/

}
